package com.lspshoping.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

public class Executor {

    public <E> List<E>  selectList(SqlMapper sqlMapper, Connection connection, Object[] args){
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<E> list = null;
        try {
            String queryString = sqlMapper.getQueryString();
            String resultType = sqlMapper.getResultType();
            Class<?> domainClass = Class.forName(resultType);
            ps = connection.prepareStatement(queryString);
            if (args != null){
                for (int i =0; i<args.length; i++){
                    ps.setObject(1+i,args[i]);
                }
            }
            rs = ps.executeQuery();
            list = new ArrayList<E>();
            while (rs.next()){

                E obj = (E)domainClass.newInstance();

                ResultSetMetaData metaData = rs.getMetaData();
                int columnCount = metaData.getColumnCount();
                for (int i = 1; i <= columnCount; i++){
                    //默认将数据库的字段转换为小写,并获取字段的值
                    String columnName = metaData.getColumnName(i).toLowerCase();
                    //如果开启了驼峰命名转换
                    if(XMLConfigBuilder.configuration.isMapUnderscoreToCamelCase()){
                        Object columnValue = rs.getObject(columnName);
                        String lineToHump = ConvertUtil.lineToHump(columnName);
                        PropertyDescriptor pd =  new PropertyDescriptor(lineToHump,domainClass);
                        Method writeMethod = pd.getWriteMethod();
                        String typeName = columnValue.getClass().getTypeName();
                        // 匹配oracle数据库的Number类型
                        if(typeName.equals("java.math.BigDecimal")){
                            String returnType = writeMethod.getParameterTypes()[0].toString();
                            if(returnType.equals( "class java.lang.Integer")){
                                writeMethod.invoke(obj,Integer.parseInt(columnValue.toString()));
                            }
                            if(returnType.equals("class java.lang.Double")) {
                                writeMethod.invoke(obj,Double.parseDouble(columnValue.toString()));
                            }
                        }else{
                            writeMethod.invoke(obj,columnValue);
                        }
                    }else {
                        Object columnValue = rs.getObject(columnName);
                        PropertyDescriptor pd =  new PropertyDescriptor(columnName,domainClass);
                        Method writeMethod = pd.getWriteMethod();
                        writeMethod.invoke(obj,columnValue);
                    }
                }
                list.add(obj);
            }
        }catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (rs != null) {
                try {
                    rs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        return list;
    }
}
